#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<assert.h>
#include<cstdlib>
#include<cstring>
using namespace std;
namespace zcg
{
	/*ostream& operator<<(ostream& out, const mystring& s);
	istream& operator>>(istream& in, mystring& s);*/
	class mystring {
	public:
		typedef char* Iterator;
		typedef const char* const_Iterator;
		void Swap(mystring& a);

		//构造函数
		mystring();
		mystring(const char* s);

		//template <class InputIterator>
		//mystring(InputIterator start, InputIterator end);

		template <class InputIterator>
		mystring(InputIterator start, InputIterator end)
			:_size(0)
			, _capacity(end - start)
		{

			_str = new char[_capacity + 1];
			while (start != end) {
				_str[_size++] = *start++;
			}
			_str[_size] = '\0';
		}


		//拷贝构造函数
		mystring(const mystring& s);

		//赋值重载
		mystring& operator=(mystring s);

		//析构函数
		~mystring();
		//获取一部分值
		size_t size()const;
		size_t capacity()const;
		bool empty();
		const char* c_str() const;
		//对空间操作
		void reserve(int n);
		void resize(int n);
		void resize(int n, char a);
		void clear();

		Iterator begin();
		Iterator end();
		const_Iterator begin()const;
		const_Iterator end()const;
		char& operator[](int n);
		char operator[](int n)const;
		//增
		void push_back(char a);
		void append(const mystring& s);
		mystring& operator+=(const mystring& s);
		mystring& operator+=(char c);
		void insert(size_t pos, const mystring& s);
		//删
		void pop_back();
		void erase(size_t pos, int len = npos);
		//查
		int find(const mystring& s, size_t pos = 0);
		int find(char c, size_t pos = 0);

		//返回字串
		const mystring substr(size_t pos = 0, int len = npos)const;

	private:
		const static int npos = -1;
		char* _str;
		size_t _size;//记录目前有多少元素
		size_t _capacity;//记录一共可以放多少个元素
	};

	//输入输出


	void mystring::Swap(mystring& a)
	{
		swap(_str, a._str);
		swap(_size, a._size);
		swap(_capacity, a._capacity);
	}

	mystring::mystring() {
		_str = nullptr;
		_size = 0;
		_capacity = 0;
	}
	mystring::mystring(const char* s)
		:_capacity(strlen(s))
		, _size(strlen(s))
	{
		_str = new char[_capacity + 1];
		strcpy(_str, s);
	}


	mystring::Iterator mystring::begin()
	{
		return _str + _size;
	}
	mystring::Iterator mystring::end()
	{
		return _str + _size;
	}
	mystring::const_Iterator mystring::begin()const
	{
		return _str;
	}
	mystring::const_Iterator mystring::end()const
	{
		return _str + _size;
	}
	char& mystring::operator[](int n)
	{
		assert(n < _size);
		return _str[n];
	}
	char mystring::operator[](int n)const
	{
		assert(n < _size);
		return _str[n];
	}
	//
	////传统写法
	//mystring::mystring(const mystring& s)
	////:_str(s._str)//浅拷贝问题
	//	:_size(s._size)
	//	,_capacity(s._capacity)
	//{
	//	_str = new char[s._size + 1];
	//	strcpy(_str, s._str);
	//}
	mystring::mystring(const mystring& s) {
		mystring a(s._str);
		Swap(a);
	}

	mystring& mystring::operator=(mystring s)
	{
		Swap(s);
		return *this;
	}
	size_t mystring::size()const
	{
		return _size;
	}

	size_t mystring::capacity()const
	{
		return _capacity;
	}

	bool mystring::empty()
	{
		return _size == 0;
	}
	const char* mystring::c_str() const
	{
		return _str;
	}
	void mystring::reserve(int n)
	{
		if (n > _capacity)//如果比原来的空间大
		{
			char* str = new char[n + 1];//开一个新空间
			strcpy(str, _str);//拷贝旧的空间到新空间
			delete _str;//释放旧空间
			_str = str;//指向新空间
			_capacity = n;
		}
	}
	void mystring::resize(int n)
	{
		reserve(n);
		while (_size < n)
		{
			_str[_size++] = '0';
		}
		_str[n] = '\0';
	}
	void mystring::resize(int n, char a)
	{
		reserve(n);
		while (_size < n)
		{
			_str[_size++] = a;
		}
		_str[n] = '\0';
	}
	void mystring::clear()
	{
		_size = 0;
	}

	void mystring::push_back(char a)
	{
		if (_size == _capacity) {
			reserve(_size * 2);
		}
		_str[_size++] = a;
		_str[_size] = '\0';
	}
	void mystring::append(const mystring& s)
	{
		if (_size + s.size() > _capacity) {
			reserve((_size + s.size()) * 2);//空间不够扩容
		}
		for (int i = 0; i < s.size(); i++)
		{
			_str[_size + i] = s[i];
		}
		_size += s.size();//更新_size
		_str[_size] = '\0';
	}
	mystring& mystring::operator+=(const mystring& s)
	{
		this->append(s);
		return *this;
	}
	mystring& mystring::operator+=(char c)
	{
		this->push_back(c);
		return *this;
	}
	void mystring::insert(size_t pos, const mystring& s)//前插
	{
		assert(pos <= _size);
		if (s.size() + _size > _capacity) {
			reserve((s.size() + _size) * 2);
		}
		size_t len = s.size();
		size_t end = _size;
		_size += s.size();
		while ((int)end >= (int)pos) {
			_str[len + end] = _str[end];
			end--;
		}
		strncpy(_str + pos, s.c_str(), len);
		_str[_size] = '\0';
	}
	void mystring::pop_back()
	{
		_str[--_size] = '\0';
	}
	void mystring::erase(size_t pos, int len)
	{
		assert(pos <= _size);
		if (len == -1 || pos + len >= _size)
		{
			_str[pos] = '\0';
		}
		else
		{
			int begin = pos + len;
			while (begin <= _size) {
				_str[begin - len] = _str[begin];//把后面所有的都移到前面
				begin++;
			}
			_size -= len;
		}
	}
	int mystring::find(const mystring& s, size_t pos)
	{
		assert(pos < _size);
		char* str = _str + pos;
		char* m = strstr(str, s.c_str());//返回_str第一次出现str的地址
		if (m)
		{
			return m - _str;
		}
		return -1;
	}
	int mystring::find(char c, size_t pos)
	{
		assert(pos < _size);
		for (int i = pos; i < _size; i++)
		{
			if (_str[i] == c)
			{
				return i;
			}
		}
		return -1;
	}

	const mystring mystring::substr(size_t pos, int len)const
	{
		if (len == -1 || pos + len >= _size)
		{
			return mystring(_str + pos);
		}
		else
		{
			mystring ans;
			for (int i = pos; i < pos + len; i++)
			{
				ans += _str[i];
			}
			return ans;
		}
		return nullptr;
	}

	ostream& operator<<(ostream& out, const mystring& s)
	{
		for (auto ch : s)
		{
			out << ch;
		}
		return out;
	}
	istream& operator>>(istream& in, mystring& s)
	{
		s.clear();//清除原本的内容；
		int i = 0;
		char buff[129];//定义一个缓冲区
		char ch = in.get();
		while (ch != '\n' && ch != ' ')
		{
			buff[i++] = ch;
			ch = in.get();
			if (i == 128)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in; 
	}
	istream& getline(istream& in, mystring& str, char delim='\n')
	{
		str.clear();
		char ch = in.get();
		while (ch != delim)
		{
			str += ch;
			ch = in.get();
		}
		return in;
	}
	mystring::~mystring() {
		delete[]_str;
		_size = 0;
		_capacity = 0;
		_str = nullptr;
	}

};
